預設 EKS[1] 使用了 CoreDNS[2] 作為 Kubernetes 內部 DNS 服務器,我們也可以根據 kubectl get deploy
命令查看 CoreDNS 資源:
$ kubectl -n kube-system get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
coredns 2/2 2 2 12d
於 Day 3 所提及於 EKS node bootstrap script 內提供了 --dns-cluster-ip
設定 CoreDNS service IP。但是這部分僅能了解 Pods 使用此 IP 作為 resolver,那為什麼 CoreDNS Pod 不會繼承此 CoreDNS Service Cluster IP,倘若繼承了此 IP 豈不是也造成了遞迴無法解析 VPC endpoint 及外部 DNS 域名。
故本文將探討 CoreDNS 設定及 EKS DNS 解析流程。
再次複習一下 EKS AMI Build Specification bootstrap.sh[3] 中,取得 --dns-cluster-ip
變數設定後更新至 kubelet 設定檔 clusterDNS
flag。
echo "$(jq ".clusterDNS=[\"$DNS_CLUSTER_IP\"]" $KUBELET_CONFIG)" > $KUBELET_CONFIG
我們也可以於 EKS worker node 上檢視相應設定,預設為 10.100.0.10
。
[ec2-user@ip-192-168-3-47 ~]$ jq .clusterDNS /etc/kubernetes/kubelet/kubelet-config.json
[
"10.100.0.10"
]
根據 kubelet[5] 文件 --cluster-dns
,為 DNS IP 地址 list,適用於每個 dnsPolicy=ClusterFirst
的 Pod。
Kubernetes Pod DNS Policy[5] 有以下四種:
Default
:Pod 繼承所在的 node 上的 DNS 解析設定。ClusterFirst
:與預設 cluster domain suffix 不相符時,如 cluster.local
,則會轉發至 node 所繼承的上游 DNS 服務器。ClusterFirstWithHostNet
:對於已設定 hostNetwork
的 Pod,則應該設置此 DNS 策略 ClusterFirstWithHostNet
。None
:此設定允許 Pod 忽略 Kubernetes 環境中的 DNS 設定。透過 kubectl run
執行啟用一個 aws-cli
Pod 並無額外設定。
$ kubectl run aws-cli --image="amazon/aws-cli" --command sleep infinity
pod/aws-cli created
檢視 dnsPolicy 確認預設使用 ClusterFirst
。這邊需要注意的是 Default
並非預設值,而 Kubernetes dnsPolicy 預設值為 ClusterFirst
。
$ kubectl get po aws-cli -o yaml | grep "dnsPolicy"
dnsPolicy: ClusterFirst
同時,檢視 Pods resolver 設定檔 /etc/resolv.conf
也能確認 nameserver
設定為 10.100.0.10
。
$ kubectl exec -it aws-cli -- cat /etc/resolv.conf
nameserver 10.100.0.10
search default.svc.cluster.local svc.cluster.local cluster.local eu-west-1.compute.internal
options ndots:5
同理,檢視 CoreDNS 所使用 dnsPolicy 為 Default
。換言之,CoreDNS 繼承使用 /etc/resolv.conf
為 EKS node 上的設定檔。
$ kubectl -n kube-system get deploy -o yaml | grep "dnsPolicy"
......
dnsPolicy: Default
不過由於 CoreDNS image 並未提供 shell 環境可以執行,以下透過設定 dnsPolicy=Default
驗證:
$ kubectl run aws-cli-2 --image="amazon/aws-cli" --command sleep infinity --overrides='{ "spec": { "dnsPolicy": "Default" } }'
pod/aws-cli-2 created
$ kubectl get po aws-cli-2 -o yaml | grep "dnsPolicy"
dnsPolicy: Default
可觀察到 Pod 使用的 nameserver
並非 10.100.0.10 而是預設 VPC DNS resolver .2
IP 地址。
$ kubectl exec -it aws-cli-2 -- cat /etc/resolv.conf
nameserver 192.168.0.2
search eu-west-1.compute.internal
options timeout:2 attempts:5
倘若登入 EKS worker node,也能觀察到相同的設定。
[ec2-user@ip-192-168-3-47 ~]$ cat /etc/resolv.conf
; generated by /usr/sbin/dhclient-script
search eu-west-1.compute.internal
options timeout:2 attempts:5
nameserver 192.168.0.2
ClusterFirst
,其 namesever 設定(/ect/resolve.conf
) 是由 kubelet --cluster-dns
參數設定,預設為 10.100.0.10
kube-dns
Service Cluster IP 將會由 iptable 路由規則轉發至對應 CoreDNS Pod。cluster.local
則會回應對應 Service 及 Pod DNS 紀錄。反之,沒有找到對應 domain name 則會回應 NXDOMAIN
。.2
IP address。.2
[6] 可以與 VPC 中關聯的服務,如 VPC endpoint 或是 Route 53 Private hosted Zone 溝通。此外,也負責將向外部進行 DNS query 。讓我們再看一下其中有幾個有趣的設定:
$ kubectl exec -it aws-cli -- cat /etc/resolv.conf
nameserver 10.100.0.10
search default.svc.cluster.local svc.cluster.local cluster.local eu-west-1.compute.internal
options ndots:5
search
:host-name lookup list。ndots
為 5:ndots
預設值為 1,對於一個 domain name 若不是 absolute name 結尾,只要 domain name 包含的 .
數量少於 ndots 定義數量,則會依照 serach
list 內順序進行解析,若 .
大於或等於 5 則會直接進行解析。因此我們也可以在 Pods 內使用 host
命令檢視此流程:
$ kubectl exec -it aws-cli -- bash
bash-4.2# yum install bind-utils -y
bash-4.2# host -av goole.com
Trying "goole.com.default.svc.cluster.local"
Trying "goole.com.svc.cluster.local"
Trying "goole.com.cluster.local"
Trying "goole.com.eu-west-1.compute.internal"
Trying "goole.com"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26185
;; flags: qr rd ra; QUERY: 1, ANSWER: 8, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;goole.com. IN ANY
;; ANSWER SECTION:
goole.com. 30 IN NS ns1083.ui-dns.org.
goole.com. 30 IN NS ns1083.ui-dns.de.
goole.com. 30 IN NS ns1083.ui-dns.com.
goole.com. 30 IN NS ns1083.ui-dns.biz.
goole.com. 30 IN SOA ns1083.ui-dns.de. hostmaster.1and1.co.uk. 2017062801 28800 7200 604800 300
goole.com. 30 IN A 217.160.0.201
goole.com. 30 IN MX 10 mx01.1and1.co.uk.
goole.com. 30 IN MX 10 mx00.1and1.co.uk.
Received 376 bytes from 10.100.0.10#53 in 61 ms
若希望優化 DNS query 次數,我們可以於 dnsPolicy 調整 ndots
數量。此外,若對於 Kubernetes 預設 ndots
設定數值為 5,也可以參考 GitHub issue #33554。
CoreDNS 預設使用 dnsPolicy
為 host 繼承 node 上的 /etc/resolv.conf
設定檔。而在 node 上預設使用了 VPC DNS resolver .2
IP,因此可以解析 VPC 內部資源,如 VPC endpoint 及 Route53 Private Zone。
上述資訊透過 EKS 所提供 Logs 來驗證上游 Kubernetes 運作原理,倘若上述內文有所錯誤,隨時可以留言或是私訊我。